//
//  ApexPushClient.h
//  ApexPush
//
//  Created by User on 2019/1/3.
//

#import <UIKit/UIKit.h>

@class ApexServer;
@class ApushMessage;
@class ApushMessageCategory;
@class ApushDataDictionary;
@class ApushDataDictionaryList;
@class ApushAlias;
@class ApushAliasList;
@class ApushIgnoreCategory;

/**
 消息事件
 */
typedef NS_ENUM(NSUInteger,ApexPushClientEvent){
    ApexPushClientEventConnecting = 0,//连接中
    ApexPushClientEventConnectError,//连接错误
    ApexPushClientEventConnectClosed,//连接关闭
    ApexPushClientEventConnected,//连接成功
    ApexPushClientEventReceiveMessage,//收到消息
    ApexPushClientEventReceiveRemoteMessage,//接收到远程消息
    ApexPushClientEventSubscribeTopic,//订阅主题
    ApexPushClientEventAlias,//别名
    ApexPushClientEventRegisterDevice,//注册设备
    ApexPushClientEventReduceBadge,//已读消息条数
    ApexPushClientEventClearBadge,//清除所有角标
    ApexPushClientEventReadDetail,//消息点击事件
    ApexPushClientEventOtherError,//其它错误
    ApexPushClientEventIgnoreCategory,//忽略栏目事件
    ApexPushClientEventReceiveReissueMessage,//收到补发消息，刷新界面事件
    ApexPushClientEventHistoryMessage,//收到历史消息,刷新界面事件
    ApexPushClientEventRejectNotice//消息免打扰
};

/**
 消息勿扰状态
 */
typedef NS_ENUM(NSUInteger,APushRejectNoticeStatus) {
    APushRejectNoticeStatusReject = 0,//勿扰
    APushRejectNoticeStatusNormal = 1//正常
};

//数据字典异步返回值
typedef void(^CategoryDataDictionary)(ApushDataDictionaryList *dataDictionaryList);
//忽略类别异步返回值
typedef void(^IgnoreCategory)(ApushIgnoreCategory *ignoreCategory);
//别名异步返回值
typedef void(^AliasBlock)(ApushAliasList *aliasList);

@protocol ApexPushClientDelegate <NSObject>

/**
 离线/在线消息输出到客户端格式
 ApexPushClientEventReceiveMessage
 ApexPushClientEventReceiveRemoteMessage
 {
     code:1,//状态
     note:'',//描述
     channel:'',//渠道
     title:'',//标题
     content:'',//内容
     badge:'',//消息角标
     extras:{},//扩展参数
     appActive:true//是否应用在前端，用来判断是否需要弹出应用内自定义消息提醒
 }
 */
@optional
//事件处理
-(void)handlePushClientEvent:(ApexPushClientEvent)event
                 eventParams:(NSDictionary *)eventParams;

@end

@interface ApexPushClient : NSObject

/**
 获取客户端实例

 @return 客户端实例
 */
+(instancetype)shareInstance;

/**
 是否开启(关闭)控制台日志
 
 @param bActive 是否激活控制台日志
 */
+(void)activeCallLog: (BOOL) bActive;

/**
 设置服务参数

 @param server 服务参数实体
 @return clientId应用唯一标识
 */
-(NSString *)setUPAPush:(ApexServer *)server;

/**
 设置代理

 @param delegate 代理
 */
-(void)setApexPushClientDelegate:(id<ApexPushClientDelegate>)delegate;

/**
 设置token

 @param deviceToken 唯一识别码
 */
-(void)bindDeviceToken:(NSString *)deviceToken;

/**
 绑定别名

 @param aliasType 别名类型
 @param alias 别名
 */
-(void)bindAlias:(NSString *)aliasType
           alias:(NSString *)alias;


/**
 解绑别名
 
 @param aliasType 别名类型
 @param alias 别名
 */
-(void)unBindAlias:(NSString *)aliasType
             alias:(NSString *)alias;

/**
 异步获取已经绑定的别名
 @param aliasBlock 异步回调
 */
-(void)fetchAsyncAlias:(AliasBlock)aliasBlock;

/**
 同步获取已经绑定的别名(必须在子线程中执行)
 @param timeout 查询超时时间(单位:秒)
 @return ApushAliasList 已经绑定的别名对象
*/
-(ApushAliasList *)fetchSyncAliasWithTimeout:(NSTimeInterval)timeout;

/**
 1.5.2新增
 根据类别同步获取字典类别列表，必须在子线程执行
 @param categorys 消息大类别数组
 @param timeout 查询超时时间(单位：秒)
 @return 查询结果
 */
-(ApushDataDictionaryList *)fetchSyncCategoryListByCategorys:(NSArray<NSString *> *)categorys timeout:(NSTimeInterval)timeout;

/**
 1.5.2新增
 根据类别异步获取字典类别列表
 @param categorys 消息大类别数组
 */
-(void)fetchAsyncCategoryListByCategorys:(NSArray<NSString *> *)categorys block:(CategoryDataDictionary)block;

/**
 根据类别获取字典类别列表
  @param categorys 消息大类别数组
 */
-(NSArray<ApushDataDictionary *> *)fetchCategoryListByCategorys:(NSArray<NSString *> *)categorys;

/**
 添加要忽略的栏目
 
 @param category 栏目code
 */
-(void)addIgnoreCategory:(NSString *)category;

/**
移除忽略的栏目

@param category 栏目code
*/
-(void)removeIgnoreCategory:(NSString *)category;

/**
 异步获取忽略类别
 */
-(void)fetchAsyncIgnoreCategorys:(IgnoreCategory)categoryBlock;
/**
 同步获取忽略类别列表(必须在子线程执行)
 */
-(ApushIgnoreCategory *)fetchSyncIgnoreCategorysWithTimeout:(NSTimeInterval)timeout;

/**
 已读条数

 @param badge 条数
 */
-(void)reduceBadge:(int)badge;
/**
 清空角标
 */
-(void)clearBadge;

/**
 释放客户端资源
 */
-(void)destroyApexPushClient;

/**
 连接服务
 */
-(void)connect;

/**
 断开服务
 */
-(void)disconnect;

/**
 服务是否已连接

 @return 连接状态
 */
- (BOOL)isConnected;

/**
 获取token

 @return token
 */
-(NSString *)getToken;

/**
 接收离线消息

 @param message 离线消息
 @param isActive app是否在前台
 */
-(void)didReceiveRemoteMessage:(NSDictionary *)message appActive:(BOOL)isActive;

/**
 离线消息同步转换

 @param message 离线消息
 @param isActive app是否在前台
 @return 消息报文
 */
-(NSDictionary *)transformSyncRemoteMessages:(NSDictionary *)message appActive:(BOOL)isActive;

/**
 消息已读回执
 
 @param messageId 消息序列id
 */
-(void)ackReadMessage:(NSString *)messageId;

/**
 消息已读回执
 
 @param messageIdArr 消息序列id数组
 */
-(void)ackReadMessages:(NSArray *)messageIdArr;

/**
 根据消息类别批量已读回执
 
 @param categorys 消息类别数组
 @return 已读条数
 */
-(NSUInteger)ackReadMessagesByCategory:(NSArray<NSString *> *)categorys;

/**
 根据消息ID阅读消息详情
 
 @param messageId 消息ID
 */
-(void)readDetail:(NSString *)messageId;

/**
 需要调用方在异步线程获取历史消息类别(栏目)列表

 @return 消息类别(栏目)列表
 */
-(NSArray<ApushMessageCategory *> *)fetchMessageCategoryList;



/**
 根据消息类别(栏目类别)需要调用方在异步线程获取消息列表

 @param messageCategorys 消息类别数组(栏目类别)
 @param page 当前页数
 @param pageSize 每页数量
 @return 某几个类别(栏目)具体消息列表
 */
-(NSArray<ApushMessage *> *)fetchMessageListByMessageCategory:(NSArray<NSString *>*)messageCategorys
                                                  currentPage:(int)page
                                                     pageSize:(int)pageSize;

/**
 需要调用方在异步线程获取未点击消息列表

 @param page 当前页数
 @param pageSize 每页数量
 @return 未点击消息列表
 */
-(NSArray<ApushMessage *> *)fetchUnclickMessageListWithCurrentPage : (int)page pageSize:(int)pageSize;

/**
 根据messageId删除一条消息

 @param messageId 消息唯一id
 */
-(BOOL)deleteMessage:(NSString *)messageId ;

/**
 根据messageId数组批量删除消息

 @param messageIdArr 消息唯一id数组
 */
-(BOOL)batchDeleteMessage:(NSArray<NSString *> *)messageIdArr;

/**
 根据类别批量删除消息
 
 @param categorys 消息类别数组
 */
-(BOOL)batchDeleteMessageByCategorys:(NSArray<NSString *> *)categorys;

/**
 离线消息免打扰
 @param status 消息状态
 */
-(void)rejectNotice:(APushRejectNoticeStatus)status;

/**
 获取当前设备消息状态
 */
-(APushRejectNoticeStatus)rejectNoticeStatus;

/**
 获取mqttclientid
 */
-(NSString*)getMqttClientId;
@end

